/*
 * Date         Author        Note
 * 2015.04.21   舞者无罪                 系统日志
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include "mh/common.h"
#include "resource.h"
#include "func.h"
#include "lang.h"
#include "log.h"
#include "com.h"
#include "mhlabel.h"

#define LOG_ITEMS_PER_PAGE       17


/*
 *
 */
static void ListLogItem(HWND hWnd)
{
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    int i = 0;
    SYS_LOG *p = GetSysLogList(g_knit_data);
    int top = 0;
    if(data.pwnd_log)
    {
        top = data.pwnd_log->top;
    }
    char sc[128] = {0};
    HWND hTmp = -1;
    for(i = 0; i < LOG_ITEMS_PER_PAGE; ++i)
    {
        if(i + top < p->total)
        {
            sprintf(sc, "%d", top + i + 1);
        }
        else
        {
            sc[0] = 0;
        }
        hTmp = GetDlgItem(hWnd, IDC_LABEL1 + i * 3);
        SetWindowCaption(hTmp, sc);
        InvalidateRect(hTmp, NULL, TRUE);
        SYS_LOG *q = GetLogItem(p, i + top);
        if(q)
        {
            time_t tt = q->time;
            struct tm *tm_now = localtime(&tt);
            sprintf(sc, "%04u/%02u/%02u-%02u:%02u:%02u",
                    tm_now->tm_year + 1900, tm_now->tm_mon + 1,
                    tm_now->tm_mday, tm_now->tm_hour, tm_now->tm_min,
                    tm_now->tm_sec);
        }
        else
        {
            sc[0] = 0;
        }
        hTmp = GetDlgItem(hWnd, IDC_LABEL1 + i * 3 + 1);
        SetWindowCaption(hTmp, sc);
        InvalidateRect(hTmp, NULL, TRUE);
        if(q)
        {
            strcat(sc, GetLogContent(q->type, q->code));
        }
        else
        {
            sc[0] = 0;
        }
        hTmp = GetDlgItem(hWnd, IDC_LABEL1 + i * 3 + 2);
        SetWindowCaption(hTmp, sc);
        InvalidateRect(hTmp, NULL, TRUE);
    }
}
/*
 *
 */
static void CreateLogInterface(HWND hWnd)
{
    //sys btn
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ESC,
        CX_LOG_BMP - CX_ASK_BMP * 2,
        10,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_FALSE]);
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ESC,
        CX_LOG_BMP - CX_ASK_BMP * 3 - 8,
        10,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_TRUE]);
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ESC,
        CX_LOG_BMP - CX_ASK_BMP * 4 - 8 * 2,
        10,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_ASK]);
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_DEL,
        15,
        15,
        50,
        25,
        hWnd, (int)&g_bmp[BMP_DEL]);

    int i = 0;
    SYS_LOG *p = GetSysLogList(g_knit_data);
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    if(data.pwnd_log)
    {
        data.pwnd_log->size = p->total;
    }
    char sc[128] = {0};
    for(i = 0; i < LOG_ITEMS_PER_PAGE; ++i)
    {
        SYS_LOG *q = GetLogItem(p, i);
        if(i < p->total)
        {
            sprintf(sc, "%d", i + 1);
        }
        else
        {
            sc[0] = 0;
        }
        CreateWindow(MH_LABEL_NAME,
            sc,
            WS_CHILD | WS_VISIBLE | BS_RIGHT,
            IDC_LABEL1 + i * 3,
            20,
            70 + i * 30,
            50,
            20,
            hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
        if(q)
        {
            time_t tt = q->time;
            struct tm *tm_now = localtime(&tt);
            sprintf(sc, "%04u/%02u/%02u-%02u:%02u:%02u", tm_now->tm_year + 1900,
                    tm_now->tm_mon + 1, tm_now->tm_mday, tm_now->tm_hour,
                    tm_now->tm_min, tm_now->tm_sec);
        }
        else
        {
            sc[0] = 0;
        }
        CreateWindow(MH_LABEL_NAME,
            sc,
            WS_CHILD | WS_VISIBLE,
            IDC_LABEL1 + i * 3 + 1,
            83,
            70 + i * 30,
            160,
            20,
            hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
        if(q)
        {
            strcat(sc, "  ");
            strcat(sc, GetLogContent(q->type, q->code));
        }
        else
        {
            sc[0] = 0;
        }
        CreateWindow(MH_LABEL_NAME,
            sc,
            WS_CHILD | WS_VISIBLE | BS_RIGHT,
            IDC_LABEL1 + i * 3 + 2,
            256,
            70 + i * 30,
            524,
            20,
            hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    }
}
/*
 *
 */
static void FlushFocusCtrl(HWND hWnd, int old_item, int new_item)
{
    HWND hTmp = GetDlgItem(hWnd, IDC_LABEL1 + old_item * 3);
    SetLabelColorStyle(hTmp, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    InvalidateRect(hTmp, NULL, TRUE);
    hTmp = GetDlgItem(hWnd, IDC_LABEL1 + old_item * 3 + 1);
    SetLabelColorStyle(hTmp, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    InvalidateRect(hTmp, NULL, TRUE);
    hTmp = GetDlgItem(hWnd, IDC_LABEL1 + old_item * 3 + 2);
    SetLabelColorStyle(hTmp, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    InvalidateRect(hTmp, NULL, TRUE);
    hTmp = GetDlgItem(hWnd, IDC_LABEL1 + new_item * 3);
    SetLabelColorStyle(hTmp, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_YELLOW);
    InvalidateRect(hTmp, NULL, TRUE);
    hTmp = GetDlgItem(hWnd, IDC_LABEL1 + new_item * 3 + 1);
    SetLabelColorStyle(hTmp, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_YELLOW);
    InvalidateRect(hTmp, NULL, TRUE);
    hTmp = GetDlgItem(hWnd, IDC_LABEL1 + new_item * 3 + 2);
    SetLabelColorStyle(hTmp, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_YELLOW);
    InvalidateRect(hTmp, NULL, TRUE);
}
/*
 *
 */
static void OnBtnCmd(HWND hWnd, int nID)
{
    switch(nID)
    {
    case ID_ESC:
        {
            PostMessage(hWnd, MSG_CLOSE, 0, 0);
        }
        break;
    case ID_DEL:
        {
            ClearSysLog(g_knit_data);
            PostMessage(hWnd, MSG_CREATE, 0, 0);
            PostMessage(hWnd, MSG_PAINT, 0, 0);
        }
        break;
    }
}
/*
 *
 */
static void OnKeyDown(HWND hWnd, uint key)
{
    if(key == SCANCODE_ESCAPE)
    {
        OnBtnCmd(hWnd, ID_ESC);
    }
    else if(key == SCANCODE_CURSORBLOCKDOWN)
    {
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        if(data.pwnd_log)
        {
            if(data.pwnd_log->active + data.pwnd_log->top + 1 < data.pwnd_log->size)
            {
                if(data.pwnd_log->active + 1 < LOG_ITEMS_PER_PAGE)
                {
                    FlushFocusCtrl(hWnd, data.pwnd_log->active, data.pwnd_log->active + 1);
                    ++data.pwnd_log->active;
                }
                else
                {
                    ++data.pwnd_log->top;
                    ListLogItem(hWnd);
                }
            }
        }
    }
    else if(key == SCANCODE_CURSORBLOCKUP)
    {
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        if(data.pwnd_log)
        {
            if(data.pwnd_log->active > 0)
            {
                FlushFocusCtrl(hWnd, data.pwnd_log->active, data.pwnd_log->active - 1);
                --data.pwnd_log->active;
            }
            else if(data.pwnd_log->top > 0)
            {
                --data.pwnd_log->top;
                ListLogItem(hWnd);
            }
        }
    }
    else if(key == SCANCODE_PAGEDOWN)
    {
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        if(data.pwnd_log)
        {
            if(data.pwnd_log->active + data.pwnd_log->top + 1 < data.pwnd_log->size)
            {
                ushort n = data.pwnd_log->active + data.pwnd_log->top;
                n += LOG_ITEMS_PER_PAGE;
                if(n < data.pwnd_log->size)
                {
                    data.pwnd_log->top += LOG_ITEMS_PER_PAGE;
                    ListLogItem(hWnd);
                }
                else
                {
                    data.pwnd_log->top = data.pwnd_log->size - LOG_ITEMS_PER_PAGE;
                    ListLogItem(hWnd);
                }
            }
        }
    }
    else if(key == SCANCODE_PAGEUP)
    {
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        if(data.pwnd_log)
        {
            if(data.pwnd_log->top >= LOG_ITEMS_PER_PAGE)
            {
                data.pwnd_log->top -= LOG_ITEMS_PER_PAGE;
                ListLogItem(hWnd);
            }
            else if(data.pwnd_log->top > 0)
            {
                data.pwnd_log->top = 0;
                ListLogItem(hWnd);
            }
        }
    }
    else if(key == SCANCODE_BACKSPACE)
    {
        OnBtnCmd(hWnd, ID_DEL);
    }
}
/*
 *
 */
static void OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    ushort x = lParam & 0xFFFF;
    ushort y = lParam >> 16;
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    if(x > 15 && x < 583 && y > 65 && y < 65 + 510 && data.pwnd_log)
    {
        int new_item = 0;
        new_item = (y - 66) / 30;
        int old_item = data.pwnd_log->active;
        if(old_item != new_item && new_item + data.pwnd_log->top < data.pwnd_log->size)
        {
            FlushFocusCtrl(hWnd, old_item, new_item);
            data.pwnd_log->active = new_item;
        }
    }
}
/*
 *
 */
static int LogWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case MSG_CREATE:
        {
            CreateLogInterface(hWnd);
        }
        break;
    case MSG_PAINT:
        {
            HDC hdc = GetClientDC(hWnd);
            RECT rect;
            GetClientRect(hWnd, &rect);
            rect.left += 200;
            rect.top += MASTER_TITLE_TOP;
            rect.right -= 200;
            rect.bottom = rect.top + MASTER_TITLE_HEIGHT - 1;
            SetBkMode(hdc, BM_TRANSPARENT);
            SetTextColor(hdc, COLOR_HQ_GREEN(hdc));
            DrawText(hdc, GetWindowCaption (hWnd), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

            WND_EXTRA_DATA data;
            int index = 0;
            if(data.pwnd_log)
            {
                index = data.pwnd_log->active;
            }

            int i = 0;
            SetPenColor(hdc, COLOR_HQ_GRAY(hdc));
            for(i = 0; i < 18; ++i)
            {
                MoveTo(hdc, 15, 65 + i * 30);
                LineTo(hdc, 783, 65 + i * 30);
            }
            MoveTo(hdc, 15, 65);
            LineTo(hdc, 15, 65 + 510);
            MoveTo(hdc, 77, 65);
            LineTo(hdc, 77, 65 + 510);
            MoveTo(hdc, 249, 65);
            LineTo(hdc, 249, 65 + 510);
            MoveTo(hdc, 783, 65);
            LineTo(hdc, 783, 65 + 510);

            ReleaseDC(hdc);
        }
        break;
    case MSG_CLOSE:
        {
            HWND hHosting = GetHosting(hWnd);
            if(hHosting != HWND_INVALID)
            {
                EnableWindow(hHosting, TRUE);
            }
            DestroyMainWindow(hWnd);
            MainWindowCleanup(hWnd);
        }
        return 0;
    case MSG_DESTROY:
        {
            ShowWindow(hWnd, SW_HIDE);
            DestroyAllControls(hWnd);
            WND_EXTRA_DATA data;
            data.value = GetWindowAdditionalData(hWnd);
            SetWindowAdditionalData(hWnd, 0);
            if(data.pwnd_log)
            {
                free(data.pwnd_log);
            }
        }
        break;
    case MSG_KEYDOWN:
        {
            OnKeyDown(hWnd, wParam);
        }
        return 0;
    case MSG_ERASEBKGND:
        {
            DrawBitmapBkGnd(hWnd, (RECT*)lParam, &g_bmp[BMP_LOG]);
        }
        return 0;
    case MSG_COMMAND:
        {
            OnBtnCmd(hWnd, LOWORD(wParam));
        }
        return 0;
    case MSG_LBUTTONDOWN:
        {
            OnLButtonDown(hWnd, wParam, lParam);
        }
        break;
    }
    return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/*
 *
 */
HWND CreateLogWindow(HWND hHosting)
{
    WND_EXTRA_DATA data;
    data.pwnd_log = calloc(1, sizeof(WND_LOG));
    int x = (CX_SCREEN - CX_LOG_BMP) / 2;
    int y = (CY_SCREEN - CY_LOG_BMP) / 2;
    MAINWINCREATE CreateInfo;
    CreateInfo.dwStyle = WS_VISIBLE;
    CreateInfo.dwExStyle = WS_EX_NONE;
    CreateInfo.spCaption = GetString(562);
    CreateInfo.hMenu = 0;
    CreateInfo.hCursor = GetSystemCursor(0);
    CreateInfo.hIcon = 0;
    CreateInfo.MainWindowProc = LogWinProc;
    CreateInfo.lx = x;
    CreateInfo.ty = y;
    CreateInfo.rx = x + CX_LOG_BMP;
    CreateInfo.by = y + CY_LOG_BMP;
    CreateInfo.iBkColor = COLOR_lightwhite;
    CreateInfo.dwAddData = data.value;
    CreateInfo.hHosting = hHosting;
    HWND hWnd = CreateMainWindow(&CreateInfo);
    if(hWnd != HWND_INVALID)
    {
        EnableWindow(hHosting, FALSE);
        ShowWindow(hWnd, SW_SHOWNORMAL);
    }
    else
    {
        free(data.pwnd_log);
    }
    return hWnd;
}
